import re
import datetime
from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings

from mlh.utils.models import BaseModel
from users import constants
from wenda.models import Qusetions
from wenda.models import Answer, Qusetions
from .models import User, GoodAt


class CreateUserSerializer(serializers.ModelSerializer):
    """注册序列化器"""
    sms_code = serializers.CharField(label='短信验证码', write_only=True)
    allow = serializers.CharField(label='同意协议', write_only=True)
    token = serializers.CharField(label='JWT token', read_only=True)

    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'sms_code', 'password', 'allow', 'token')

        extra_kwargs = {
            'username': {
                'min_length': 2,
                'max_length': 20,
                'error_messages': {
                    'min_length': '仅允许2-20个字符的用户名',
                    'max_length': '仅允许2-20个字符的用户名',
                }
            },
            'password': {
                'write_only': True,
                'min_length': 8,
                'max_length': 20,
                'error_messages': {
                    'min_length': '仅允许8-20个字符的密码',
                    'max_length': '仅允许8-20个字符的密码',
                }
            }
        }

    def validate_mobile(self, value):
        """验证手机号"""
        if not re.match(r'^1[3-9]\d{9}$', value):
            raise serializers.ValidationError('手机号格式错误')
        return value

    def validate_allow(self, value):
        """检验用户是否同意协议"""
        if value != 'true':
            raise serializers.ValidationError('请同意用户协议')
        return value

    def validate(self, attrs):
        """校验短信验证码"""
        sms_code = attrs['sms_code']
        mobile = attrs['mobile']
        redis_conn = get_redis_connection('verify')
        real_sms_code = redis_conn.get('sms_%s' % mobile)
        # 校验
        if not real_sms_code:
            raise serializers.ValidationError("短信验证码已过期")
        if sms_code != real_sms_code.decode():
            raise serializers.ValidationError("短信验证码错误")

        return attrs

    def create(self, validated_data):
        """
        创建用户
        """
        del validated_data['sms_code']
        del validated_data['allow']
        user = super().create(validated_data)
        user.set_password(validated_data['password'])
        user.save()

        # 手动签发JWT
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)  # 在载荷部分添加用户信息
        token = jwt_encode_handler(payload)  # 编码生成token
        user.token = token

        return user


class CheckUserSerializer(serializers.ModelSerializer):
    """用户登陆序列化器"""
    token = serializers.CharField(label='JWT token', read_only=True)
    username = serializers.CharField(label='用户名', read_only=True)
    avatar = serializers.ImageField(label='头像', read_only=True)
    mobile = serializers.CharField(label='手机号')

    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'avatar', 'password', 'token')
        extra_kwargs = {
            'password': {
                'write_only': True
            },
            "mobile": {
                'write_only': True
            }
        }

    def validate_mobile(self, value):
        """验证手机号"""
        if not re.match(r'^1[3-9]\d{9}$', value):
            raise serializers.ValidationError('手机号格式错误')
        return value

    def validate(self, attrs):
        mobile = attrs['mobile']
        password = attrs['password']

        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            raise serializers.ValidationError("用户不存在")

        if not user.check_password(password):
            raise serializers.ValidationError("密码错误")

        # 手动签发JWT
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)  # 在载荷部分添加用户信息
        token = jwt_encode_handler(payload)  # 编码生成token
        user.token = token

        return user


class UserSkillSerializer(serializers.ModelSerializer):

    """用户技能序列化器"""

    class Meta:
        model = GoodAt
        fields = ('id', 'skill')


class UserDetailSerializer(serializers.ModelSerializer):

    """用户详情页序列化器"""
    # 用户技能需要返回的数据格式　[{id, skill}, {id, skill}, ...]
    good_at = UserSkillSerializer(many=True, read_only=True)

    class Meta:
        # (username, city, school, introduction, 真人姓名, gender,avatar,
        #  出身日期, mobile, email, experience, education, skills)
        model = User
        fields = ('id', 'username', 'city', 'school', 'introduction', 'truename',
                  'gender', 'avatar', 'birth', 'mobile', 'email', 'experience',
                  'education', 'good_at', 'company', 'personurl')


class UserChangeDetailSerializer(serializers.ModelSerializer):
    """用户个人档案修改序列化器"""
    birth = serializers.CharField(required=False, allow_null=True)
    gender = serializers.IntegerField(required=False, allow_null=True)
    personurl = serializers.CharField(required=False, allow_null=True)

    class Meta:
        model = User
        fields = '__all__'

    # def validated_birth(self, value):
    #     value = datetime.datetime.strptime(value, '%Y-%m-%d')
    #     return value


class UserInfoSerializer(serializers.ModelSerializer):
    """
    用户账户页面
    """
    class Meta:
        model = User
        fields = ('id', 'username', 'city', 'school', 'introduction',
                   'mobile', 'email', 'company', 'personurl')


class UserChangeEduExpSerializer(serializers.ModelSerializer):
    """用户教育%经历序列化器"""
    class Meta:
        model = User
        fields = ('education', 'experience')


class UserQuestionSerializer(serializers.ModelSerializer):
    """问题序列化器"""
    class Meta:
        model = Qusetions
        fields = ('title', 'like_count')


class UserAnswerSerializer(serializers.ModelSerializer):
    """用户回答问题序列化器"""
    question = UserQuestionSerializer(read_only=True)

    class Meta:
        model = Answer
        fields = ('question', 'update_time')



class UserMyquestserializer(serializers.ModelSerializer):

    create_time = BaseModel()

    class Meta:
        model = Qusetions
        fields = ('create_time', "like_count", "title", 'id')